package com.bjpowernode.common.aspect;

import java.util.List;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.bjpowernode.common.DataScope;
import com.bjpowernode.constant.Constants;
import com.bjpowernode.query.BaseQuery;
import com.bjpowernode.util.JWTUtils;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;

@Component
@Aspect
public class DataScopeAspect {

	// 切入点
	@Pointcut(value = "@annotation(com.bjpowernode.common.DataScope)")
	private void pointCut() {

	}

	@Around(value = "pointCut()")
	public Object process(ProceedingJoinPoint joinPoint) throws Throwable {

		// 获取加了@DataScope注解的方法
		MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

		// 拿到方法上的注解
		DataScope dataScope = methodSignature.getMethod().getDeclaredAnnotation(DataScope.class);

		String tableAlias = dataScope.tableAlias();
		String tableField = dataScope.tableField();

		// 在Spring web容器中，可以拿到当前请求的request对象
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();

		String token = request.getHeader(Constants.TOKEN_NAME);

		// 从token中解析出该用户是管理员还是普通用户
		// 用户角色
		List<String> roleList = JWTUtils.parseJWTByUserRole(token);
		// 用户id
		Integer userId = JWTUtils.parseJWTByUserId(token);

		// 不包含admin角色,只查当前用户的数据
		if (!roleList.contains("admin")) {
			Object params = joinPoint.getArgs()[0];
			if (params instanceof BaseQuery) {
				BaseQuery query = (BaseQuery) params;
				// select * from t_user tu where tu.id = 2 （普通用户）
				String sql = " and " + tableAlias + "." + tableField + "=" + userId;
				query.setFilterSQL(sql);
			}
		}
		
		System.out.println("目标方法执行前...");
		Object result = joinPoint.proceed();
		System.out.println("目标方法执行后...");
		
		return result;
	}
}
